﻿using System;
using System.Threading;
using NUnit.Framework;
using Assert = NUnit.Framework.Assert;

namespace Jet.Utilities.Tests
{
	[TestFixture]
	public class DisposableResourceTests
	{
		[Test]
		public void BasicTest()
		{
			var resource = new DisposableResourceMoc();
			Assert.IsFalse(resource.PublicDisposed);
			Assert.IsFalse(resource.DisposeResourceCalled);
			resource.Dispose();
			Assert.IsTrue(resource.PublicDisposed);
			Assert.IsTrue(resource.DisposeResourceCalled);
			Assert.IsFalse(resource.DisposedFromGC);
		}

		[Test]
		public void UsingTest()
		{
			DisposableResourceMoc resource;
			using (resource = new DisposableResourceMoc())
			{
				Assert.IsFalse(resource.PublicDisposed);
				Assert.IsFalse(resource.DisposeResourceCalled);
			}
			Assert.IsTrue(resource.PublicDisposed);
			Assert.IsTrue(resource.DisposeResourceCalled);
			Assert.IsFalse(resource.DisposedFromGC);
		}

		[Test]
		public void DoubleDisposingTest()
		{
			var resource = new DisposableResourceMoc();
			Assert.IsFalse(resource.PublicDisposed);
			resource.Dispose();
			Assert.IsTrue(resource.PublicDisposed);
			Assert.IsTrue(resource.DisposeResourceCalled);
			Assert.IsFalse(resource.DisposedFromGC);
			resource.DisposeResourceCalled = false;
			resource.Dispose();
			Assert.IsFalse(resource.DisposeResourceCalled);
		}

		[Test]
		public void ImitateGCTest()
		{
			var resource = new DisposableResourceMoc();
			Assert.IsFalse(resource.PublicDisposed);
			resource = null;
			DisposableResourceMoc.InstanceDisposed = false;
			DisposableResourceMoc.DisposedFromGCStatic = false;
			GC.Collect(3, GCCollectionMode.Forced, true);
			GC.WaitForPendingFinalizers();
			Assert.IsTrue(DisposableResourceMoc.InstanceDisposed);
			Assert.IsTrue(DisposableResourceMoc.DisposedFromGCStatic);
		}
	}
}
